#pragma once

template<typename T>
class SingletonFactory
{
public:
	template <typename... Args>
	static T* instance(Args... args) { return new T(args...); }
};

template<typename T, typename TFty = SingletonFactory<T>>
class Singleton
{
	Singleton(const Singleton&) = delete;
	const Singleton& operator=(const Singleton&) = delete;
protected:
	static T* pInstance;
public:
	Singleton() {}
	~Singleton() {}

	template <typename... Args>
	static T* instance(Args... args)
	{
		if (!pInstance)
			pInstance = TFty::instance(args...);

		return pInstance;
	}
		
	template <typename... Args>
	static T& getMe(Args... args) { return *instance(args...); }
	static void delMe() 
	{ 
		delete pInstance;
		pInstance = nullptr;
	}
};
template<typename T, typename TFty>
T* Singleton<T, TFty>::pInstance =nullptr;